const path = require('path')
// 路径引入
const resolve = dir => {
    return path.join(__dirname, dir)
}
// gzip压缩文件插件
const CompressionPlugin = require('compression-webpack-plugin')
// 是否是构建环境
const isProd = ['production', 'stage'].includes(process.env.NODE_ENV)
// 代码编辑器插件
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
// 系统名称
const name = process.env.VUE_APP_TITLE || '统一开发平台'
// 环境配置
module.exports = {
    /**
     * 基本路径
     * 这里可根据部署需求去做修改。
     * 比如部署的时候要求该项目放在（/myProject）目录下。
     * 那么这里的跟路径也需要改成该目录的名称
     */
    publicPath: process.env.VUE_APP_BASE_PATH
        ? process.env.VUE_APP_BASE_PATH
        : '/',
    // 构建时的输出目录
    outputDir: process.env.VUE_APP_OUT_DIR
        ? process.env.VUE_APP_OUT_DIR
        : 'dist-prod',
    // 用于放置生成的静态资源 (js、css、img、fonts) 的；（项目打包之后，静态资源会放在这个文件夹下）
    assetsDir: 'static',
    /* 默认：true,是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码 */
    lintOnSave: true,
    /* 默认：false,是否使用包含运行时编译器的 Vue 构建版本 */
    runtimeCompiler: false,
    /* 默认：[],通过 Babel 显式转译 node_modules 中的一个依赖 */
    transpileDependencies: [],
    /* 默认：true,是否在构建生产包时生成 sourceMap 文件，false将提高构建速度 */
    productionSourceMap: isProd ? false : true,
    /* 设置生成的 HTML 中 <link rel="stylesheet"> 和 <script> 标签的 crossorigin 属性 */
    // crossorigin: 'undefined',
    /* 默认：false,在生成的 HTML 中的 <link rel="stylesheet"> 和 <script> 标签上启用 Subresource Integrity (SRI)。如果你构建后的文件是部署在 CDN 上的，启用该选项可以提供额外的安全性 */
    integrity: false,
    configureWebpack: {
        module: {
            rules: [
                {
                    test: /\.mjs$/,
                    include: /node_modules/,
                    type: 'javascript/auto'
                }
            ]
        }
    },
    // 插件相关配置
    chainWebpack: config => {
        if (isProd) {
            // 去除控制台打印
            config.optimization.minimizer('terser').tap(args => {
                // 注释console.*
                args[0].terserOptions.compress.drop_console =
                    process.env.VUE_APP_DROP_DROP_CONSOLE
                // remove debugger
                args[0].terserOptions.compress.drop_debugger =
                    process.env.VUE_APP_DROP_DEBUGGER
                // 移除 console.log
                args[0].terserOptions.compress.pure_funcs = ['console.log']
                // 去掉注释 如果需要看chunk-vendors公共部分插件，可以注释掉就可以看到注释了
                args[0].terserOptions.output = {
                    comments: false
                }
                return args
            })
            // gzip插件
            config.plugin('compressionPlugin').use(
                new CompressionPlugin({
                    filename: '[path][base].gz',
                    algorithm: 'gzip',
                    //用['js', 'css']有个缺点就是map文件也会压缩,这时候压缩就没多大意义,用正则会更好一点
                    test: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i,
                    // 单位bytes, 大于10k才会考虑压缩
                    threshold: 10240,
                    // 默认压缩率, 压缩结果能低于百分之八十才会进行压缩
                    minRatio: 0.8
                    // deleteOriginalAssets: true //是否删除源文件(不推荐删除, 容易出现chunk报错问题)
                })
            )
            // 拆包
            config.optimization.splitChunks({
                chunks: 'all',
                minSize: 20000, // 允许新拆出 chunk 的最小体积，也是异步 chunk 公共模块的强制拆分体积
                cacheGroups: {
                    libs: {
                        // 第三方库
                        name: 'chunk-libs',
                        test: /[\\/]node_modules[\\/]/,
                        priority: 10,
                        chunks: 'initial' // 只打包初始时依赖的第三方
                    }
                }
            })
            // 分析 webpack 的总打包耗时以及每个 plugin 和 loader 的打包耗时
            config
                .plugin('speed-measure')
                .use(require('speed-measure-webpack-plugin'))

            // 打包进度
            config
                .plugin('progress')
                .use(require('simple-progress-webpack-plugin'), [
                    { format: 'minimal' }
                ])

            config.optimization.runtimeChunk('single'),
                {
                    from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
                    to: './' //到根目录下
                }
        }
        config.plugins.delete('preload') // TODO: need test
        config.plugins.delete('prefetch') // TODO: need test
        config.name = name
        // 修复热更新失效
        config.resolve.symlinks(true)
        // 修改文件引入自定义路径
        config.resolve.alias
            .set('@', resolve('src'))
            .set('@assets', resolve('src/assets'))
            .set('@components', resolve('src/components'))
            .set('@views', resolve('src/views'))
            .set('@store', resolve('src/store'))
        // 修改项目标题
        config.plugin('html').tap(args => {
            args[0].title = process.env.VUE_APP_TITLE || '通用项目模板'
            return args
        })
        config.plugin('MonacoWebpackPlugin').use(new MonacoWebpackPlugin())
        // SVG图标处理
        config.module
            .rule('svg')
            .exclude.add(resolve('src/assets/icons'))
            .end()
        config.module
            .rule('icons')
            .test(/\.svg$/)
            .include.add(resolve('src/assets/icons'))
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
            .options({ symbolId: 'icon-[name]' })
            .end()
    },
    // css配置
    css: {
        loaderOptions: {
            css: {
                // 这里的选项会传递给 css-loader
            },
            postcss: {
                // 这里的选项会传递给 postcss-loader
            },
            sass: {
                prependData: '@import "~@/assets/styles/index.scss";'
            }
        }
    },
    // server配置
    devServer: {
        overlay: {
            // 让浏览器 overlay 同时显示警告和错误
            warnings: true,
            errors: true
        },
        host: '0.0.0.0',
        port: 8080, // 端口号
        https: false, // https:{type:Boolean}
        open: false, //配置自动启动浏览器
        hotOnly: true // 热更新
    }
}
